home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr40 / x1j4_src.zip / TNL7IP.C < prev    next >
Text File  |  1995-03-10  |  26KB  |  817 lines

  1. /*****************************************************************************/
  2. /*                                              */
  3. /*                                         */
  4. /*    *****              *****                      */
  5. /*     *****            *****                         */
  6. /*       *****          *****                         */
  7. /*         *****        *****                         */
  8. /*  ***************      ***************                     */
  9. /*  *****************    *****************                     */
  10. /*  ***************      ***************                     */
  11. /*         *****        *****       TheNet                    */
  12. /*       *****          *****       Portable. Compatible.         */
  13. /*     *****            *****       Public Domain             */
  14. /*    *****              *****    NORD><LINK                  */
  15. /*                                         */
  16. /* This software is public domain ONLY for non commercial use                */
  17. /*                                                                           */
  18. /*                                         */
  19. /*****************************************************************************/
  20.  
  21. /* Level 7B IP switch commands                             */
  22. /* Version 1                                       */
  23. /* Dave Roberts G8KBB                                 */
  24. /* 10-April-1992                                 */
  25. /* This software is written for the purposes of self-instruction in the
  26.  * subject of Amateur Radio. It is not complete or correct, it is not
  27.  * claimed that it works. It is not to be sold or to be used commercially 
  28.  * or to be used in life critical or similar circumstances
  29.  */
  30.  
  31. /*
  32.  * September 1993 - released as TheNet X-1J
  33.  */
  34.  
  35. #include "all.h"
  36. #include "tntyp.h"        /* Definition der Typen                 */
  37. #include "tnl7be.h"
  38. #include "ip.h"
  39. #include "icmp.h"
  40. #define EXTERN extern
  41. #include "ipv.h"
  42.  
  43. /* The following structures are used to display information
  44.  * from the iproute and arp commands
  45.  */
  46.  
  47. char *if_modes[] = { "  ", "DG", "VC" };
  48. char *if_names[] = { "Net/Rom", "Port 0",  "Port 1" };
  49.  
  50. /* ***************************************************************************
  51.  * Function    : ccpipr - The IProute command
  52.  *
  53.  * Inputs    : none explicitly. Reads globals of clicnt and clipoi
  54.  *
  55.  * Outputs    : an updated route table and a display to the user
  56.  *
  57.  * Operation    : Management of the ip routes table
  58.  * -------------------------------------------------------------------------*/
  59. VOID ccpipr()
  60. {
  61.     ipaddr host, gateway;
  62.     unsigned bits, metric;
  63.     signed port;
  64.     register mhtyp *bufpoi;
  65.     register IP_ROUTE_MB *iprmb;
  66.     char *clipoitmp;
  67.     register unsigned i = 1;
  68.     
  69.     bits = 32;
  70.     host.Short[1] = host.Short[0] = gateway.Short[1] = 
  71.     gateway.Short[0] = metric = 0;
  72.  
  73.     /* first, if no parameters are given, drop thru to display
  74.      */
  75.     if( clicnt > 0 )
  76.     {
  77.         /* a valid address must be the first parameter,
  78.          * followed optionally by the number of bits
  79.          */
  80.         if( get_ip_addr( &host, &clicnt, &clipoi ) )
  81.         {
  82.             i = 0;
  83.             if( skipspace() )
  84.             {
  85.                 if( *clipoi == '/' )
  86.                 {
  87.                     nxtcli();
  88.                     if( (bits = nextnumber() )  > 32 )
  89.                         goto no_change_route;
  90.                 }
  91.  
  92.                 /* the sysop only commands are '+' and '-'
  93.                  */
  94.                 if( issyso() )
  95.                 {
  96.                     switch( *clipoi )
  97.                     {
  98.                         case '-':
  99.                             rt_drop( &host, bits );
  100.                             break;
  101.                         case '+':
  102.                             nxtcli();
  103.                             if( skipspace() )
  104.                             {
  105.                                 if( upcase( *clipoi ) == 'N' )
  106.                                     port = 0;
  107.                                 else if(*clipoi >='0' && *clipoi < NUMPORTS+'0')
  108.                                     port = *clipoi - '0'+1;
  109.                                 else
  110.                                     goto no_change_route;
  111.                                 i = clicnt;
  112.                                 clipoitmp = clipoi;
  113.                                 if( skipnext( &clicnt, &clipoi ) )
  114.                                     if( !get_ip_addr( &gateway, &clicnt, &clipoi ) )
  115.                                     {
  116.                                         clipoi = clipoitmp;
  117.                                         clicnt = i;
  118.                                     }
  119.                                 if( skipnext( &clicnt, &clipoi ) )
  120.                                     metric = nextnumber();
  121.                                 rt_add( &host, bits, &gateway, port, metric, 0, 0 );
  122.                             }
  123.                     }
  124.                 }
  125.             }
  126.         }
  127.     }
  128. no_change_route:
  129. #ifdef USELONG
  130.     host.Long &= ~0L << ( 32-bits );
  131. #else
  132.     ip_mask( &host, bits );
  133. #endif
  134.     bufpoi = putals("\015Destination      Len  I/F     Gateway           Metric");
  135.     for( iprmb = (IP_ROUTE_MB *)IP_Routes.lnext;
  136.          iprmb != (IP_ROUTE_MB *)&IP_Routes.lnext;
  137.          iprmb = (IP_ROUTE_MB *)iprmb->link.lnext )
  138.         if( i )
  139.             showroute( &iprmb->route, bufpoi );
  140. #ifdef USELONG
  141.         else if(host.Long == iprmb->route.dest.Long && bits == iprmb->route.bits)
  142. #else
  143.         else if(host.Short[0] == iprmb->route.dest.Short[0] &&
  144.                 host.Short[1] == iprmb->route.dest.Short[1] && 
  145.                 bits == iprmb->route.bits)
  146. #endif
  147.         {
  148.             showroute( &iprmb->route, bufpoi );
  149.             break;
  150.         }
  151.     seteom( bufpoi );
  152. }
  153.  
  154. /* ***************************************************************************
  155.  * Function    : display a single route entry in ip route table
  156.  *
  157.  * Inputs    : pointer into route table and output buffer pointer
  158.  *
  159.  * Outputs    : no return value
  160.  *
  161.  * Operation    : take route table entry, convert to ascii & put in buffer
  162.  * -------------------------------------------------------------------------*/
  163. VOID showroute( rp, bufpoi )
  164. register IP_ROUTE *rp;
  165. register mhtyp *bufpoi;
  166. {
  167.     putchr( '\015', bufpoi );
  168.     bufpoi->l4time = bufpoi->putcnt;        /* mark position    */
  169.     show_ip_addr( &rp->dest, bufpoi );        /* display address  */
  170.     putspa( 18, bufpoi );                /* tab in to 18     */
  171.     putnum( rp->bits, bufpoi );            /* disp bits value  */
  172.     putspa( 22, bufpoi );                /* tab in again     */
  173.     putstr( if_names[rp->interface], bufpoi );    /* show port        */
  174.     putspa( 30, bufpoi );                /* tab in to 30     */
  175. #ifdef USELONG                        /* if gateway set,..*/
  176.     if( rp->gateway.Long != 0 )
  177. #else
  178.     if( rp->gateway.Short[0] != 0 || rp->gateway.Short[1] != 0 )
  179. #endif
  180.         show_ip_addr( &rp->gateway, bufpoi );    /* display gateway  */
  181.     putspa( 48, bufpoi );                /* tab in to 40     */
  182.     if( rp->metric != 0 )                /* if metric set,   */
  183.         putnum( rp->metric, bufpoi );        /* show metric      */
  184.     return;
  185. }
  186.  
  187. /* ***************************************************************************
  188.  * Function    : show an ip address as ascii
  189.  *
  190.  * Inputs    : a pointer to an address and a pointer to an o/p buffer
  191.  *
  192.  * Outputs    : no return value
  193.  *
  194.  * Operation    : take each byte in turn, and convert to hex with '.' between
  195.  * -------------------------------------------------------------------------*/
  196. VOID show_ip_addr( address, bufpoi )
  197. register ipaddr *address;
  198. register mhtyp *bufpoi;
  199. {
  200.     register int i;
  201.     
  202.     for( i=3; i >= 0 ; i-- )
  203.     {
  204.         putnum( address->Bytes[i], bufpoi );
  205.         if( i ) 
  206.             putchr( '.', bufpoi );
  207.     }
  208. }
  209.  
  210.  
  211. /* ***************************************************************************
  212.  * Function    : get an ip address from input buffer
  213.  *
  214.  * Inputs    : pointer to o/p ip address buffer, clicnt & clipoi
  215.  *
  216.  * Outputs    : return 0 if syntax error, 1 if converted OK
  217.  *
  218.  * Operation    : extract in sequence, 4 numbers & 3 'dots' nnn.nnn.nnn.nnn
  219.  * -------------------------------------------------------------------------*/
  220.  
  221. get_ip_addr( target, count, ptr )
  222. ipaddr *target;
  223. register signed *count;
  224. register char **ptr;
  225. {
  226.     unsigned addr[4];
  227.     register signed int i;
  228.  
  229.     for( i=0; i<4; i++ )
  230.     {
  231.         if( ( addr[i] = nxtnum( count, ptr ) ) > 255 )
  232.             return( FALSE );
  233.         if( i < 3 )
  234.         {
  235.             if( *count < 1 || **ptr != '.' )
  236.                 return( FALSE );
  237.             else
  238.             {
  239.                 (*ptr)++;
  240.                 (*count)--;
  241.             }
  242.         }
  243.     }
  244.     for( i=3; i>=0; i-- )
  245.         target->Bytes[i] = addr[3-i];
  246.     return( TRUE );
  247. }
  248.  
  249. /* ***************************************************************************
  250.  * Function    : Command line interpreter for arp table changes/display
  251.  *
  252.  * Inputs    : no parameters, reads clicnt, clipoi & arp table
  253.  *
  254.  * Outputs    : no return value. Updates table.
  255.  *
  256.  * Operation    : add entry if requested, show new entry or whole table
  257.  * -------------------------------------------------------------------------*/
  258. VOID ccparp()
  259. {
  260.     ipaddr host;
  261.     char hwtype, dgmode;
  262.     register unsigned i;
  263.     register mhtyp *bufpoi;
  264.     register ARP_TAB_MB *arpmb;
  265.     char call[7];
  266.     unsigned publish;
  267.     char c;
  268.  
  269.     host.Short[1] = host.Short[0] = publish = 0;
  270.  
  271.     /* if a parameter is passed, try to parse command line
  272.      * otherwise just drop into whole table display.
  273.      * the syntax is, initially, an address followed by '-' or '+'
  274.      * but only the sysop may add or delete !
  275.      */
  276.     if( clicnt > 0 )
  277.     {
  278.         if( get_ip_addr( &host, &clicnt, &clipoi ) )
  279.         {
  280.             if( issyso() )
  281.             {
  282.                 switch( *clipoi )
  283.                 {
  284.                     case '-':
  285.                         nxtcli();
  286.                         if( skipspace() )
  287.                         {
  288.                             switch( upcase( *clipoi ) )
  289.                             {
  290.                                 case 'N':
  291.                                     hwtype = ARP_NETROM;
  292.                                     break;
  293.                                 case 'A':
  294.                                     hwtype = ARP_AX25;
  295.                                     break;
  296.                                 default:
  297.                                     goto no_change_arp;
  298.                             }
  299.                             arp_drop( &host, hwtype );
  300.                         }
  301.                         break;
  302.                     case '+':
  303.                         nxtcli();
  304.                         if( skipspace() && upcase(*clipoi)=='P')
  305.                         {
  306.                             nxtcli();
  307.                             publish = 1;
  308.                         }
  309.                         if( skipspace() )
  310.                         {
  311.                             switch( upcase( *clipoi ) )
  312.                             {
  313.                                 case 'N':
  314.                                     hwtype = ARP_NETROM;
  315.                                     break;
  316.                                 case 'A':
  317.                                     hwtype = ARP_AX25;
  318.                                     break;
  319.                                 default:
  320.                                     goto no_change_arp;
  321.                             }
  322.  
  323.                             /* We have address, '+' and subnet type, now
  324.                              * we need a hardware address ( ie a callsign )
  325.                              * and optionally a mode ( dg/vc )
  326.                              */
  327.                             skipnext( &clicnt, &clipoi );
  328.                             if( !getcal( &clicnt, &clipoi, 1, call ) )
  329.                                 goto no_change_arp;
  330.                             if( skipspace()  &&
  331.                                 (c=upcase(*clipoi)) == 'D' )
  332.                                 dgmode = 1;
  333.                             else if( c == 'V' )
  334.                                 dgmode = 2;
  335.                             else
  336.                                 dgmode = 0;
  337.                             arp_add( &host, hwtype, call, dgmode, 0, publish );
  338.                         }
  339.                 }
  340.             }
  341.         }
  342.     }
  343. no_change_arp:
  344.     bufpoi = putals("\015Destination       P hw-type Callsign   Mode  Timer");
  345. #ifdef USELONG
  346.         i = ( host.Long == 0 );
  347. #else
  348.         i = ( host.Short[0] == 0  && host.Short[1] == 0 );
  349. #endif
  350.     for( arpmb = (ARP_TAB_MB *)Arp_tab.lnext;
  351.          arpmb != (ARP_TAB_MB *)&Arp_tab.lnext;
  352.          arpmb = (ARP_TAB_MB *)arpmb->link.lnext )
  353.         if( ( i != 0 ) ||
  354. #ifdef USELONG
  355.             (host.Long == arpmb->arp.dest.Long ) )
  356. #else
  357.             (host.Short[0] == arpmb->arp.dest.Short[0] &&
  358.                 host.Short[1] == arpmb->arp.dest.Short[1] ) )
  359. #endif
  360.             showarp( &arpmb->arp, bufpoi );
  361.     seteom( bufpoi );
  362. }
  363.  
  364.  
  365. /* ***************************************************************************
  366.  * Function    : showarp()
  367.  *
  368.  * Inputs    : pointer to an arp table entry and a message buffer pointer
  369.  *
  370.  * Outputs    : no return value. Text added to bufpoi for arp entry
  371.  *
  372.  * Operation    : create text version of arp entry & put into buffer
  373.  * -------------------------------------------------------------------------*/
  374. VOID showarp( arp, bufpoi )
  375. register ARP_TAB *arp;
  376. register mhtyp *bufpoi;
  377. {
  378.     putchr( '\015', bufpoi );
  379.     bufpoi->l4time = bufpoi->putcnt;
  380.     show_ip_addr( &arp->dest, bufpoi );
  381.     putspa( 18, bufpoi );
  382.     putstr( ( arp->publish_flag ? "P " : "  " ), bufpoi );
  383.     putstr( ( arp->hwtype ? "AX.25" : if_names[0] ) , bufpoi );
  384.     putspa( 28, bufpoi );
  385.     putid( arp->callsign, bufpoi );
  386.     putspa( 40, bufpoi );
  387.     putstr( if_modes[ arp->dgmode & 3 ], bufpoi );
  388.     if( arp->timer != 0 )
  389.     {
  390.         putspa( 46, bufpoi );
  391.         putnum( arp->timer, bufpoi );
  392.     }
  393. }
  394.  
  395. /* ***************************************************************************
  396.  * Function    : ccpipa() - the node ip address command line interpreter
  397.  *
  398.  * Inputs    : no parameters. reads clicnt, clipoi & my_ip_address
  399.  *
  400.  * Outputs    : no return value. Updates my_ip_address & shows it in bufpoi
  401.  *
  402.  * Operation    : if sysop & if new addr given update ip address. Display it
  403.  * -------------------------------------------------------------------------*/
  404. VOID ccpipa()
  405. {
  406.     ccp_ip_help( &my_ip_addr, "My" );
  407. }
  408.  
  409. VOID ccp_ip_help( ip_addr, name )
  410. register ipaddr *ip_addr;
  411. char *name;
  412. {
  413.     register mhtyp *bufpoi;
  414.  
  415.     if( issyso() )
  416.         get_ip_addr( ip_addr, &clicnt, &clipoi );
  417.     bufpoi = putals( name );
  418.     putstr( " IP address : ", bufpoi );
  419.     show_ip_addr( ip_addr, bufpoi );
  420.     seteom( bufpoi );
  421. }
  422.  
  423. /* ***************************************************************************
  424.  * Function    : ccpipb() - the node ip b'cast address command line interpreter
  425.  *
  426.  * Inputs    : no parameters. reads clicnt, clipoi & bcast_ip_address
  427.  *
  428.  * Outputs    : no return value. Updates bcast_ip_address & shows it in bufpoi
  429.  *
  430.  * Operation    : if sysop & if new addr given update ip address. Display it
  431.  * -------------------------------------------------------------------------*/
  432. VOID ccpipb()
  433. {
  434.     ccp_ip_help( &bcast_ip_addr, "Broadcast" );
  435. }
  436.  
  437. /* ***********************************************************************
  438.  * This is the parameter table for the ip router.
  439.  * The first entry controls the port default L2 modes
  440.  * The rest is the IP MIB
  441.  * It is structured as per PARMS etc to allow re-use of common code
  442.  */
  443.  
  444. partyp iptab[] = {
  445.     &Ip_mib[0].value.integer,    0,    MAXPORTMASK,
  446.     &Ip_mib[1].value.integer,    0,    1,
  447.     &Ip_mib[2].value.integer,    2,    MAXTTL,
  448.     &Ip_mib[3].value.integer,    0,    0,
  449.     &Ip_mib[4].value.integer,    0,    0,
  450.     &Ip_mib[5].value.integer,    0,    0,
  451.     &Ip_mib[6].value.integer,    0,    0,
  452.     &Ip_mib[7].value.integer,    0,    0,
  453.     &Ip_mib[8].value.integer,    0,    0,
  454.     &Ip_mib[9].value.integer,    0,    0,
  455.     &Ip_mib[10].value.integer,    0,    0,
  456.     &Ip_mib[11].value.integer,    0,    0,
  457.     &Ip_mib[12].value.integer,    0,    0,
  458.     &Ip_mib[13].value.integer,    1,    65535,
  459.     &Ip_mib[14].value.integer,    0,    0,
  460.     &Ip_mib[15].value.integer,    0,    0,
  461.     &Ip_mib[16].value.integer,    0,    0,
  462.     &Ip_mib[17].value.integer,    0,    0,
  463.     &Ip_mib[18].value.integer,    0,    0,
  464.     &Ip_mib[19].value.integer,    0,    0
  465. };
  466.  
  467. /* ***************************************************************************
  468.  * Function    : ccpips() - the ip stats parameters command
  469.  *
  470.  * Inputs    : none - reads IP MIB passes it on to ccp_par()
  471.  *
  472.  * Outputs    : as per ccp_par
  473.  *
  474.  * Operation    : updates and / or displays IP MIB data
  475.  * -------------------------------------------------------------------------*/
  476. VOID ccpips()
  477. {
  478.     ccp_par( iptab, ( sizeof( iptab ) / sizeof( struct param ) ) );
  479. }
  480.  
  481. /* ***************************************************************************
  482.  * Function    : ccpart() - the arp control parameters command
  483.  *
  484.  * Inputs    : none - passes table details on to ccp_par
  485.  *
  486.  * Outputs    : as per ccp_par
  487.  *
  488.  * Operation    : updates and / or displays ARP data
  489.  * -------------------------------------------------------------------------*/
  490.  
  491. partyp arptab[] =
  492. {
  493.     &ARPrunning,    0,    1,
  494.     &ARPtimer,    15,    24*60
  495. };
  496.  
  497.  
  498. VOID ccpart()
  499. {
  500.     ccp_par( arptab, ( sizeof( arptab ) / sizeof( struct param ) ) );
  501. }
  502.  
  503. /* ***********************************************************************
  504.  * as per iptab, this is the ICMP MIB. It is not currently used
  505.  */
  506. #ifdef ICMPSTATS
  507.  
  508. partyp icmptab[] = {
  509.     &Icmp_mib[1].value.integer,    0,    0,
  510.     &Icmp_mib[2].value.integer,    0,    0,
  511.     &Icmp_mib[3].value.integer,    0,    0,
  512.     &Icmp_mib[4].value.integer,    0,    0,
  513.     &Icmp_mib[5].value.integer,    0,    0,
  514.     &Icmp_mib[6].value.integer,    0,    0,
  515.     &Icmp_mib[7].value.integer,    0,    0,
  516.     &Icmp_mib[8].value.integer,    0,    0,
  517.     &Icmp_mib[9].value.integer,    0,    0,
  518.     &Icmp_mib[10].value.integer,    0,    0,
  519.     &Icmp_mib[11].value.integer,    0,    0,
  520.     &Icmp_mib[12].value.integer,    0,    0,
  521.     &Icmp_mib[13].value.integer,    0,    0,
  522.     &Icmp_mib[14].value.integer,    0,    0,
  523.     &Icmp_mib[15].value.integer,    0,    0,
  524.     &Icmp_mib[16].value.integer,    0,    0,
  525.     &Icmp_mib[17].value.integer,    0,    0,
  526.     &Icmp_mib[18].value.integer,    0,    0,
  527.     &Icmp_mib[19].value.integer,    0,    0,
  528.     &Icmp_mib[20].value.integer,    0,    0,
  529.     &Icmp_mib[21].value.integer,    0,    0,
  530.     &Icmp_mib[22].value.integer,    0,    0,
  531.     &Icmp_mib[23].value.integer,    0,    0,
  532.     &Icmp_mib[24].value.integer,    0,    0,
  533.     &Icmp_mib[25].value.integer,    0,    0,
  534.     &Icmp_mib[26].value.integer,    0,    0
  535. };
  536.  
  537.  
  538.  
  539. /* ***************************************************************************
  540.  * Function    : ccpics() - the icmp stats parameters command
  541.  *
  542.  * Inputs    : none - reads ICMP MIB passes it on to ccp_par()
  543.  *
  544.  * Outputs    : as per ccp_par
  545.  *
  546.  * Operation    : updates and / or displays ICMP MIB data
  547.  * -------------------------------------------------------------------------*/
  548. VOID ccpics()
  549. {
  550.     ccp_par( icmptab, ( sizeof( icmptab ) / sizeof( struct param ) ) );
  551. }
  552.  
  553. #endif
  554.  
  555. /* ***************************************************************************
  556.  * Function    : rt_add
  557.  *
  558.  * Inputs    : pointer to host address
  559.  *          number of significant bits in address
  560.  *          pointer to gateway address ( if zero, no gateway )
  561.  *          port number ( order as per interfaces structure )
  562.  *          metric
  563.  *          time to live in seconds before route entry explodes
  564.  *          flag to say if this route is private
  565.  *
  566.  * Returns    : true / false return on whether route table updated
  567.  *          updates routing table
  568.  *
  569.  * Operation    : add route to routing table, or update if already there
  570.  * -------------------------------------------------------------------------*/
  571.  
  572. rt_add( target, bits, gateway, iface, metric, ttl, private )
  573. ipaddr *target;
  574. unsigned bits;
  575. ipaddr *gateway;
  576. signed iface;
  577. unsigned metric;
  578. unsigned ttl;
  579. BOOLEAN private;
  580. {
  581.     IP_ROUTE_MB *iprp;
  582.     register IP_ROUTE_MB *iprp2;
  583.     ipaddr temp;
  584.  
  585.     if( !route_find( &iprp, &temp, target, bits ) )
  586.     {
  587.         iprp2 = (IP_ROUTE_MB *)allocb();
  588.         relink( iprp2, iprp->link.lprev );
  589.         iprp = iprp2;
  590.     }
  591.     iprp2 = iprp;
  592. #ifdef USELONG
  593.     iprp2->route.dest.Long = temp.Long;
  594.     iprp2->route.gateway.Long = gateway->Long;
  595. #else
  596.     iprp2->route.dest.Short[0] = temp.Short[0];
  597.     iprp2->route.dest.Short[1] = temp.Short[1];
  598.     iprp2->route.gateway.Short[0] = gateway->Short[0];
  599.     iprp2->route.gateway.Short[1] = gateway->Short[1];
  600. #endif
  601.     iprp2->route.bits = bits;
  602.     iprp2->route.interface = iface;
  603.     iprp2->route.metric = metric;
  604.     iprp2->route.timer = ttl;
  605.     iprp2->route.flags = private ? RTPRIVATE : 0 ;
  606.     return( TRUE );
  607. }
  608.  
  609.  
  610. /* ***************************************************************************
  611.  * Function    : route_find() - locates ip route table entry for given address
  612.  *
  613.  * Inputs    : pointer to pointer to result, ptr to masked ( real ) result,
  614.  *            pointer to desired target ip address & number if IP addr bits
  615.  *
  616.  * Returns    : boolean result, masked value of address in temp and pointer
  617.  *            to ip route table entry in iprptr
  618.  *
  619.  * Operation : look for a match of (bits) bits to address (target) in the
  620.  *             ip route table. Give Boolean result & pointer to the entry      
  621.  * -------------------------------------------------------------------------*/
  622. route_find( iprptr, temp, target, bits )
  623. IP_ROUTE_MB **iprptr;
  624. register ipaddr *temp;
  625. ipaddr *target;
  626. register unsigned bits;
  627. {
  628.     register IP_ROUTE_MB *iprp;
  629.  
  630. #ifdef USELONG
  631.     temp->Long = target->Long;
  632. #else
  633.     temp->Short[0] = target->Short[0];
  634.     temp->Short[1] = target->Short[1];
  635. #endif
  636.     if( bits > 32 ) 
  637.         bits = 32;
  638. #ifdef USELONG
  639.     temp->Long &= ~0L << 32-bits;
  640. #else
  641.     ip_mask( temp, bits );
  642. #endif
  643.     IP_Route_Cache.route = NULLROUTE;
  644.     for( iprp = (IP_ROUTE_MB *)IP_Routes.lnext;
  645.          iprp != (IP_ROUTE_MB *)&IP_Routes.lnext && bits <= iprp->route.bits;
  646.          iprp = (IP_ROUTE_MB *)iprp->link.lnext )
  647. #ifdef USELONG
  648.         if( iprp->route.dest.Long == temp->Long && iprp->route.bits == bits )
  649. #else
  650.         if( iprp->route.dest.Short[0] == temp->Short[0] && 
  651.             iprp->route.dest.Short[1] == temp->Short[1] && 
  652.             iprp->route.bits == bits )
  653. #endif
  654.         {
  655.             *iprptr = iprp;
  656.             return( TRUE );
  657.         }
  658.     *iprptr = iprp;
  659.     return( FALSE );
  660. }
  661.  
  662. /* ***************************************************************************
  663.  * Function    : rt_drop() - delete an entry in the ip route table
  664.  *
  665.  * Inputs    : ip address pointer and number of bits significance
  666.  *
  667.  * Returns    : boolean result. Also updates the ip route table
  668.  *
  669.  * Operation    : look for target in ip route table. Delete if found.
  670.  * -------------------------------------------------------------------------*/
  671.  
  672. rt_drop( target, bits )
  673. ipaddr *target;
  674. unsigned bits;
  675. {
  676.     IP_ROUTE_MB *iprp;
  677.     ipaddr temp;
  678.  
  679.     if( route_find( &iprp, &temp, target, bits ) )
  680.     {
  681.         dealoc( unlink( iprp ) );
  682.         return( TRUE );
  683.     }
  684.     return( FALSE );
  685. }
  686.  
  687. /* ***************************************************************************
  688.  * Function    : arp_add() - make an entry in the arp table
  689.  *
  690.  * Inputs    : IP address, hardware type, hardware address( callsign),
  691.  *            datagram mode flag, time to live and published entry flag
  692.  *
  693.  * Returns    : boolean result of success / failure of operation
  694.  *            currently, it *can* only succeed !
  695.  *
  696.  * Operation    : find existing entry & update it or make a new entry
  697.  *                in the arp table.
  698.  *                IMPORTANT - the table is not arranged as a set of tables
  699.  *                for each bit length. Rather it is stored in descending
  700.  *                order of significant bits.
  701.  * -------------------------------------------------------------------------*/
  702. arp_add( target, hwtype, callsign, dgmode, ttl, publish )
  703. register ipaddr *target;
  704. char *callsign;
  705. BOOLEAN dgmode;
  706. unsigned ttl, hwtype;
  707. BOOLEAN publish;
  708. {
  709.     ARP_TAB_MB *arprp;
  710.     register ARP_TAB_MB *arprp2;
  711.  
  712.     if( !find_arp( &arprp, target, hwtype ) )
  713.     {
  714.         arprp = (ARP_TAB_MB *)allocb();
  715.         relink( arprp, Arp_tab.lnext );
  716.     }
  717.     arprp2 = arprp;
  718. #ifdef USELONG
  719.     arprp2->arp.dest.Long = target->Long;
  720. #else
  721.     arprp2->arp.dest.Short[0] = target->Short[0];
  722.     arprp2->arp.dest.Short[1] = target->Short[1];
  723. #endif
  724.     arprp2->arp.hwtype = hwtype;
  725.     arprp2->arp.timer = ttl;
  726.     arprp2->arp.publish_flag = publish;
  727.     arprp2->arp.dgmode = dgmode;
  728.     cpyid( arprp2->arp.callsign, callsign );
  729.     return( TRUE );
  730. }
  731.  
  732. /* ***************************************************************************
  733.  * Function    : find_arp() - tell me the hardware address for an IP address
  734.  *
  735.  * Inputs    : pointer to result, desired IP address and hardware type
  736.  *
  737.  * Returns    : boolean result & pointer to entry in arpptr
  738.  *
  739.  * Operation    : scan the arp table for a match for the target address
  740.  *                for a given hardware address. If found, point to address
  741.  *                and say it succeeded.
  742.  * -------------------------------------------------------------------------*/
  743. find_arp( arpptr, target, hwtype )
  744. ARP_TAB_MB **arpptr;
  745. ipaddr *target;
  746. unsigned hwtype;
  747. {
  748.     register ARP_TAB_MB *arprp;
  749.  
  750.     for( arprp = (ARP_TAB_MB *)Arp_tab.lnext;
  751.          arprp != (ARP_TAB_MB *)&Arp_tab.lnext;
  752.          arprp = (ARP_TAB_MB *)arprp->link.lnext )
  753. #ifdef USELONG
  754.         if( (arprp->arp.dest.Long == target->Long) && 
  755.             (hwtype == arprp->arp.hwtype) )
  756. #else
  757.         if( arprp->arp.dest.Short[0] == target->Short[0] &&
  758.             arprp->arp.dest.Short[1] == target->Short[1] &&
  759.             (hwtype == arprp->arp.hwtype) )
  760. #endif
  761.         {
  762.             *arpptr = arprp;
  763.             return( TRUE );
  764.         }
  765.     return( FALSE );
  766. }
  767.  
  768. /* ***************************************************************************
  769.  * Function    : arp_drop() - delete an entry in the arp table
  770.  *
  771.  * Inputs    : desired ip addess & number of bits
  772.  *
  773.  * Returns    : boolean on result. Updates arp table
  774.  *
  775.  * Operation    : Find arp table match. Delete it if found. Tell me so.
  776.  * -------------------------------------------------------------------------*/
  777. arp_drop( target, hwtype )
  778. ipaddr *target;
  779. unsigned hwtype;
  780. {
  781.     ARP_TAB_MB *arprp;
  782.  
  783.     if( find_arp( &arprp, target, hwtype ) )
  784.     {
  785.         dealoc( unlink( arprp ) );
  786.         return( TRUE );
  787.     }
  788.     return( FALSE );
  789. }
  790.  
  791. /*- End of IP router switch commands ---------------------------------------*/
  792.  
  793. /*- start of IP router timer service routine--------------------------------*/
  794.  
  795. arpsrv()
  796. {
  797.     register ARP_TAB_MB *arprp;
  798.     register ARP_TAB_MB *arp;
  799.  
  800.     if( ARPrunning && --ARPcounter == 0 )
  801.     {
  802.         ARPcounter = 60;
  803.         for( arprp = (ARP_TAB_MB *)Arp_tab.lnext;
  804.              arprp != (ARP_TAB_MB *)&Arp_tab.lnext;
  805.            )
  806.         {
  807.             arp = arprp;
  808.             arprp = (ARP_TAB_MB *)arprp->link.lnext;
  809.             if( arp->arp.timer != 0 && --arp->arp.timer == 0 )
  810.                 arp_drop( &arp->arp.dest, arp->arp.hwtype );
  811.         }
  812.     }
  813. }
  814.  
  815.  
  816. /*- end of IP router timer service routine----------------------------------*/
  817.